package com.company;

import java.util.*;

public class DFA {

    public static void main(String[] args) {

        String txt = "测试文段的内容，分配我呢间类型给结合，的和，嘿嘿,fffff，我是中国人";
        ArrayList<String> strings = new ArrayList<>();

        strings.add("测试");
        strings.add("内容");
        strings.add("fff");
        strings.add("中国");
        strings.add("中国人");

        // 构建敏感词库
        addSensitiveWords(new HashSet<>(strings));

        long time = new Date().getTime();

        // 获取文章中的敏感词
        Set<String> sensitiveWords = getSensitiveWords(txt, 1);

        // 敏感词替换
        String result = filterString(txt, sensitiveWords);

        System.out.println("耗时：" + (new Date().getTime() - time) + "毫秒");

        System.out.println(result);

    }

    private static String filterString(String txt, Set<String> sensitiveWords)
    {
        Iterator<String> iterator = sensitiveWords.iterator();

        while (iterator.hasNext())
        {
            // 每一次获取出来的都是一个敏感词
            String next = iterator.next();
            txt = txt.replaceAll(next,getAsterisk(next.length()));
        }

        return txt;

    }

    // 初始化敏感词集合
    public static HashMap SensitiveWordSet;

    // 创建敏感词集合
    public static void addSensitiveWords(Set<String> strings)
    {
        SensitiveWordSet = new HashMap(strings.size());

        Iterator<String> iterator = strings.iterator();

        while (iterator.hasNext())
        {
            Map temporary = SensitiveWordSet;

            String next = iterator.next();

            for (int a = 0 ; a < next.length() ; a++)
            {
                char key = next.charAt(a);

                Map valueMap = (Map) temporary.get(key);

                if (valueMap != null)
                {
                    temporary = valueMap;
                }else
                {
                    Map newMap = new HashMap();
                    newMap.put("isEnd","0");
                    temporary.put(key,newMap);
                    temporary = newMap;
                }

                if ( a == next.length() -1 )
                {
                    temporary.put("isEnd","1");
                }

            }
        }

    }

    // 获取敏感词
    public static Set<String> getSensitiveWords(String txt , int matchinRules)
    {
        Set<String> resultSet = new HashSet<>();

        for (int a = 0 ; a < txt.length() ; a++)
        {
            // 检索过滤词
            int resultCount = searchSensitiveWords(txt , a , matchinRules);
            if (resultCount > 0)
            {
                String substring = txt.substring(a, a + resultCount);
                resultSet.add(substring);
                a = a + resultCount - 1;
            }
        }
        return resultSet;
    }

    // 检索过滤词
    private static int searchSensitiveWords(String txt, int index, int matchinRules)
    {
        boolean flag = false;

        int count = 0;

        Map temporary = SensitiveWordSet;

        for (int a = index ; a < txt.length() ; a++)
        {
            char key = txt.charAt(a);

            temporary = (Map) temporary.get(key);

            if (temporary != null)
            {
                count++;

                if ("1".equals(temporary.get("isEnd")))
                {
                    flag = true;
                    if (matchinRules == 1)
                    {
                        // 最小匹配规则
                        break;
                    }
                }
            }else
            {
                break;
            }
        }
        if (count < 2 || !flag)
        {
            count = 0;
        }
        return count;
    }

    // 获取 * 号字符串
    // size：要获取多少个 * 号的字符串
    private static String getAsterisk(int size)
    {
        StringBuilder stringBuilder = new StringBuilder();
        for (int a = 0 ; a < size ; a++)
        {
            stringBuilder.append("*");
        }
        return stringBuilder.toString();
    }
}
